package ca.llsutherland.nfl.facade;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import ca.llsutherland.nfl.dao.ConferenceDao;
import ca.llsutherland.nfl.dao.DivisionDao;
import ca.llsutherland.nfl.dao.PersonDao;
import ca.llsutherland.nfl.dao.RoleDao;
import ca.llsutherland.nfl.dao.SeasonDao;
import ca.llsutherland.nfl.dao.TeamDao;
import ca.llsutherland.nfl.dao.UserDao;
import ca.llsutherland.nfl.dao.WeekTypeDao;
import ca.llsutherland.nfl.domain.Conference;
import ca.llsutherland.nfl.domain.Division;
import ca.llsutherland.nfl.domain.Person;
import ca.llsutherland.nfl.domain.Role;
import ca.llsutherland.nfl.domain.Season;
import ca.llsutherland.nfl.domain.Team;
import ca.llsutherland.nfl.domain.User;
import ca.llsutherland.nfl.domain.WeekType;
import ca.llsutherland.nfl.exception.ValidationException;
import ca.llsutherland.nfl.persistence.Transaction;
import ca.llsutherland.nfl.persistence.TransactionHandler;

public class CreationFacade extends BaseFacade{

	protected TransactionHandler transactionHandler = TransactionHandler.getInstance();

	public Role createRole(final Role role) {
		assertValidNewRole(role);
        
        Transaction t = new Transaction() {
            public Object executeTransaction() throws ValidationException {
                return RoleDao.getInstance().create(role);
            }
        };
        return (Role) this.transactionHandler.runTransaction(t);
	}

	public User createUser(final User user) {
		assertValidNewUser(user);
		Transaction t = new Transaction() {
            public Object executeTransaction() throws ValidationException {
            	List<Person> newlyCreatedPeople = new ArrayList<Person>();
            	
            	//First, create the user with their role included
            	User newlyCreatedUser = UserDao.getInstance().create(user);
            	
            	//create the people and pass in the USER ID
            	for (Person person : user.getPeople()) {
            		person.setUserId(newlyCreatedUser.getId());
            		newlyCreatedPeople.add(PersonDao.getInstance().create(person));
				}
                
            	Collections.sort(newlyCreatedPeople);
            	newlyCreatedUser.setPeople(newlyCreatedPeople);
				return newlyCreatedUser;
            }
        };
        return (User) this.transactionHandler.runTransaction(t);
	}

	public Person createPerson(final Person person) {
		assertValidNewPerson(person);
		
		Transaction t = new Transaction() {
            public Object executeTransaction() throws ValidationException {
                return PersonDao.getInstance().create(person);
            }
        };
        return (Person) this.transactionHandler.runTransaction(t);
	}

	public Conference createConference(final Conference conference) {
		assertValidNewConference(conference);
		
		Transaction t = new Transaction() {
            public Object executeTransaction() throws ValidationException {
                return ConferenceDao.getInstance().create(conference);
            }
        };
        return (Conference) this.transactionHandler.runTransaction(t);
	}

	public Division createDivision(final Division division) {
		assertValidNewDivision(division);
		
		Transaction t = new Transaction() {
            public Object executeTransaction() throws ValidationException {
                return DivisionDao.getInstance().create(division);
            }
        };
        return (Division) this.transactionHandler.runTransaction(t);
	}

	public Team createTeam(final Team team) {
		assertValidNewTeam(team);
		
		Transaction t = new Transaction() {
			public Object executeTransaction() throws ValidationException {
				return TeamDao.getInstance().create(team);
			}
		};
		return (Team) this.transactionHandler.runTransaction(t);
		
	}

	public Season createSeason(final Season season) {
		assertValidNewSeason(season);
		
		Transaction t = new Transaction() {
			public Object executeTransaction() throws ValidationException {
				return SeasonDao.getInstance().create(season);
			}
		};
		return (Season) this.transactionHandler.runTransaction(t);
		
	}

	public WeekType createWeekType(final WeekType weekType) {
		assertValidNewWeekType(weekType);
		
		Transaction t = new Transaction() {
			public Object executeTransaction() throws ValidationException {
				return WeekTypeDao.getInstance().create(weekType);
			}
		};
		return (WeekType) this.transactionHandler.runTransaction(t);
	}

	
}
